home *** CD-ROM | disk | FTP | other *** search
- /*
- * $Filename: telnetd.c $
- * $Revision: 2.0 $
- * $Date: 1995/04/13 19:53:48 $
- *
- * Copyright (C) 1993,94 by Steve Holland <sdh4@cornell.edu>
- * Copyright (C) 1995 by Peter Simons <simons@peti.rhein.de>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id: telnetd.c 2.0 1995/04/13 19:53:48 simons Exp $
- *
- */
-
- /************************************* includes ***********/
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <sys/param.h>
- #include <dos/dos.h>
- #include <dos/dosextens.h>
- #include <dos/dostags.h>
- #include <proto/dos.h>
- #include <proto/exec.h>
- #include <proto/utility.h>
- #include <proto/usergroup.h>
- #include <errno.h>
- #include <sys/ioctl.h>
- #include <exec/errors.h>
- #include <devices/serial.h>
- #include <string.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <inetd.h>
- #include <syslog.h>
- #include <amitcp/socketbasetags.h>
-
- #include <fakesr.h>
-
- #include "telnetd_rev.h"
-
- /************************************* structures *********/
- struct InstData {
- struct Library *DOSB;
- struct Library *SocketB;
- struct Library *UtilityB;
- struct Library *UserGroupB;
- int Socket;
- signed short RecvBuf[1024];
- int RecvBufPos;
- int RecvBufFlags;
- };
-
- struct PasswdInfo {
- char Login[50];
- char Passwd[50];
- char RealName[150];
- char WorkDir[256];
- char Command[512];
- };
-
- /************************************* defines ************/
- #define DOSBase Inst->DOSB
- #define UtilityBase Inst->UtilityB
- #define SocketBase Inst->SocketB
- #define UserGroupBase Inst->UserGroupB
- #define Socket Inst->Socket
-
- /* telnet symbols */
- #define IAC 255
- #define WILL 251
- #define WONT 252
- #define DO 253
- #define DONT 254
- #define ECHO 1
- #define LINEMODE 34
- #define SE 240
- #define SB 250
- #define MODE 1
- #define EDIT 1
-
- #define RBF_SUBNEGOTIATE (1<<0) /* Defines for RecvBufFlags */
-
- /************************************* global variables ***/
- static const char __DOSVer[] = VERSTAG " written by Peter Simons <simons@peti.rhein.de>";
- #ifndef USE_INETD
- struct Library *SysBase;
- #endif
- char *Signature="FAKEMSG--EXPUNGE";
-
- /************************************* prototypes *********/
- void SockPuts(struct InstData *Inst,int Sock,char *Buf);
- void SockGets(struct InstData *Inst,int Sock,char *Buf,int BufSize);
- unsigned long GetInt(char *String,char **NewPtr);
- struct PasswdInfo *LookupPasswd(struct InstData *Inst,char *Login);
- int __asm SubSubProc(register __a0 char *ArgString,register __d0 long Length);
- struct DosPacket *PktFromMsg(struct Message *Msg);
- void MakeLongStr(char *StrBuf,unsigned long Num);
- void SockWrite(struct InstData *Inst,int Sock,char *Buf,int Len,int RawFlag);
- int RecvChar(struct InstData *Inst,int Sock,unsigned char *Loc,int RawMode);
- struct Process *MyCreateNewProcTags(struct InstData *,ULONG,...);
- void *MyAllocDosObjectTags(struct InstData *,ULONG,ULONG,...);
- void PktFPuts(struct InstData *Inst,BPTR File,char *String);
- void SockRawWrite(struct InstData *Inst,int Sock,char *Buf,int Len);
- void MySystemTags(struct Library *DSBse,char *Cmd,ULONG Tag0,...);
- void mystrcat(char *Dest,char *Cat);
- void MyFPrintf(struct InstData *Inst,BPTR File,char *Fmt,...);
-
- ULONG FakeBeginIO(void *IORequest);
- ULONG FakeAbortIO(void *IORequest);
- ULONG FakeOpen(void *IORequest);
- ULONG FakeClose(void *IORequest);
- void mymovmem(char *From,char *To,int Len);
-
- #define NewList(list) {(list)->lh_Head=(struct Node *)&(list)->lh_Tail;(list)->lh_Tail=NULL;(list)->lh_TailPred=(struct Node *)&(list)->lh_Head;}
-
- #ifdef DEBUG
- BPTR DebugFile;
- #endif
-
- #ifdef USE_INETD
- int main(void)
- #else
- int __asm main(register __a0 char *ArgStr,register __d0 long Length)
- /* ArgString will look like: "[SocketID] [SigNum] [ParentTaskID]" */
- #endif
- {
- int Cnt;
- unsigned long SockID,SigID,TaskID;
- char Buf[1000],LoginBuf[50], MyPrgName[64];
- BPTR BannerFile=NULL;
- struct InstData *Inst=NULL;
- struct PasswdInfo *Info=NULL;
- struct FileHandle *FH;
- struct Message *Msg,*GotMsg;
- unsigned char NoEcho[7];
- unsigned char Echo[14];
- char *ArgString;
- int OpenCount=0;
- int AmntRead;
- int HangupFlag=FALSE;
-
- ULONG SigMask;
- long yes=TRUE;
- fd_set RdSet;
- fd_set WrSet;
- struct List ReadWaitList;
- struct DosPacket *Pkt;
- int Err;
- unsigned char Chr,NumBuf[30];
- int RawMode=FALSE;
- int NextChar=-1;
- struct MsgPort *TimePort;
- struct timerequest *TimeReq;
- struct DaemonMessage *InetdStartup;
- struct Process *Self;
-
-
- #ifndef USE_INETD
- SysBase=*((struct Library **)0x00000004);
- ArgString=ArgStr;
- #endif
- Echo[0]=NoEcho[0]=IAC;
- Echo[1]=WONT;
- Echo[2]=ECHO;
- Echo[3]=IAC;
- Echo[4]=DO;
- Echo[5]=LINEMODE;
- Echo[6]=IAC;
- Echo[7]=SB;
- Echo[8]=LINEMODE;
- Echo[9]=MODE;
- Echo[10]=EDIT;
- Echo[11]=IAC;
- Echo[12]=SE;
- NoEcho[1]=WILL;
- NoEcho[2]=ECHO;
- NoEcho[3]=IAC;
- NoEcho[4]=DONT;
- NoEcho[5]=LINEMODE;
- Echo[13]=NoEcho[6]='\0';
-
- #ifndef USE_INETD
- for (Cnt=0;Cnt < Length;Cnt++) {
- if (ArgStr[Cnt]!=' ' && (ArgStr[Cnt] < '0' || ArgStr[Cnt] > '9'))
- return ERROR_FILE_NOT_OBJECT;
- }
- #endif
- Inst=AllocMem(sizeof(struct InstData),MEMF_CLEAR);
- if (!Inst) return 0;
- DOSBase=OpenLibrary("dos.library",36);
- UtilityBase=OpenLibrary("utility.library",36);
- SocketBase=OpenLibrary("bsdsocket.library",2);
- UserGroupBase=OldOpenLibrary(USERGROUPNAME);
-
- TimePort=CreateMsgPort();
- NewList(&ReadWaitList);
-
- if (!DOSBase || !UtilityBase || !SocketBase || !UserGroupBase || !TimePort) return 0;
-
- SocketBaseTags(SBTM_SETVAL(SBTC_LOGTAGPTR), "telnetd",
- SBTM_SETVAL(SBTC_LOGSTAT), 0,
- SBTM_SETVAL(SBTC_LOGFACILITY), LOG_AUTH,
- TAG_END);
-
- #ifdef DEBUG
- DebugFile=Open("con:0/0/500/100/telnetd DEBUG/WAIT/CLOSE",MODE_OLDFILE);
- FPuts(DebugFile,"telnetd starting\n");
- # ifndef USE_INETD
- FPuts(DebugFile,"ArgString=");
- FPuts(DebugFile,ArgString);
- FPuts(DebugFile,"\n");
- # endif
-
- #endif
-
- #ifdef USE_INETD
- Self=(struct Process *) FindTask(NULL);
- InetdStartup=(struct DaemonMessage *)Self->pr_ExitData;
- if (!InetdStartup) goto quit;
- Socket=ObtainSocket(InetdStartup->dm_Id,InetdStartup->dm_Family,InetdStartup->dm_Type,0);
- if (Socket < 0) goto quit;
- #else
- /* Get arguments */
- SockID=GetInt(ArgString,&ArgString);
- ArgString++; /* Skip over space */
- SigID=GetInt(ArgString,&ArgString);
- ArgString++; /* Skip over space */
- TaskID=GetInt(ArgString,&ArgString);
- /* After this call, the parameter string is no longer valid */
- Signal((struct Task *)TaskID,1<<SigID);
- #ifdef DEBUG
- FPuts(DebugFile,"Signaled parent\n");
- #endif
-
- /* We're on our own now */
- Socket=ObtainSocket(SockID,AF_INET,SOCK_STREAM,0);
- if (Socket < 0) goto quit;
-
- #endif
-
- #ifdef DEBUG
- FPuts(DebugFile,"Got Socket\n");
- #endif
-
- /* First, display banner, ask for password, etc */
- if (BannerFile=Open("AmiTCP:db/telnetd_banner",MODE_OLDFILE)) {
- int len = 1;
-
- while(TRUE) {
- len = Read(BannerFile, Buf, sizeof(Buf));
- if (!len || len == -1)
- break;
- SockWrite(Inst,Socket,Buf,len,FALSE);
- }
- Close(BannerFile);
- }
-
- #ifdef DEBUG
- FPuts(DebugFile,"Wrote banner to socket\n");
- #endif
- /* Get login name */
- SockPuts(Inst,Socket,"Login: ");
- SockPuts(Inst,Socket,Echo);
- SockGets(Inst,Socket,LoginBuf,sizeof(LoginBuf));
- while (strlen(LoginBuf) && (LoginBuf[strlen(LoginBuf)-1]=='\n' || LoginBuf[strlen(LoginBuf)-1]=='\r'))
- LoginBuf[strlen(LoginBuf)-1]='\0';
- #ifdef DEBUG
- FPuts(DebugFile,"Got Login: ");
- FPuts(DebugFile,LoginBuf);
- FPuts(DebugFile,"\n");
- #endif
-
- Info = LookupPasswd(Inst, LoginBuf);
-
-
- /*
- * We don't need a password if the password is "*"
- * AND the shell is not equal "nologin".
- *
- * Otherwise get a password, even if the user doesn't exist at all.
- */
- if (!Info || !(!strcmp(Info->Passwd, "*") && strcmp("nologin", Info->Command))) {
- strcpy(Buf, "Password: ");
- strcpy(Buf+strlen(Buf), NoEcho);
- SockPuts(Inst, Socket, Buf);
- SockGets(Inst, Socket, Buf,sizeof(Buf));
- while (strlen(Buf) && (Buf[strlen(Buf)-1]=='\n' || Buf[strlen(Buf)-1]=='\r'))
- Buf[strlen(Buf)-1]='\0';
- SockPuts(Inst,Socket,Echo);
- #ifdef DEBUG
- FPuts(DebugFile,"Got Password: ");
- FPuts(DebugFile,Buf);
- FPuts(DebugFile,"\n");
- #endif
- if (!Info || !strcmp("nologin", Info->Command) || strcmp(Info->Passwd, crypt(Buf, Info->Passwd))) {
- if (Info)
- syslog(LOG_INFO, "Unsuccessful login attempt from user %s", Info->Login);
- SockPuts(Inst,Socket,"\nLogin incorrect.\nClosing connection\n");
- CloseSocket(Socket);
- goto quit;
- }
- }
-
- SockPuts(Inst,Socket,"\n");
-
- syslog(LOG_INFO, "User %s logged in successfully", Info->Login);
- sprintf(MyPrgName, "telnetd <%s>", Info->Login);
- SetProgramName(MyPrgName);
-
- if (Info->Command[0]=='*') {
- /* Use stdin/stdout */
- /* Make myself a filehandle */
- #ifdef DEBUG
- FPuts(DebugFile,"Logged in OK\nMaking Filehandle\n");
- #endif
-
- FH=MyAllocDosObjectTags(Inst,DOS_FILEHANDLE,ADO_FH_Mode,MODE_OLDFILE,TAG_END);
- if (!FH) goto quit;
- FH->fh_Pos=FH->fh_End=-1;
- FH->fh_Type=&((struct Process *)FindTask(NULL))->pr_MsgPort;
- FH->fh_Args=(LONG)Info;
- FH->fh_Port=FH->fh_Type; /* Is this right? */
- FH=(struct FileHandle *)MKBADDR(FH);
- OpenCount++;
-
- /* Run the subprocess */
- MakeLongStr(Buf,(ULONG)FH);
- strcpy(Buf+strlen(Buf)," ");
- strcpy(Buf+strlen(Buf),Info->Command+1 /* ignore the leading '*' */);
- #ifdef DEBUG
- FPuts(DebugFile,"Starting subprocess\nCmdLine=");
- FPuts(DebugFile,Buf);
- FPuts(DebugFile,"\n");
- /*Close(DebugFile);*/
- Flush(DebugFile);
-
- /*DebugFile=NULL;*/
- #endif
-
- /* NO more DOS calls allowed after this one */
- /* We also can't use Buf after we make this call */
- if (*(Info->Command+1)) {
- MyCreateNewProcTags(Inst,NP_Entry,SubSubProc,
- NP_Arguments,Buf,
- TAG_END);
- }
- FD_ZERO(&RdSet);
- IoctlSocket(Socket,FIONBIO,(caddr_t)&yes);
- #ifdef DEBUG
- PktFPuts(Inst,DebugFile,"Starting handler support\n");
- #endif
- for (;;) {
- if (ReadWaitList.lh_Head->ln_Succ && !HangupFlag) {
- if (NextChar != -1) {
- Pkt=PktFromMsg((struct Message *)ReadWaitList.lh_Head);
- *(((unsigned char *)Pkt->dp_Arg2)+Pkt->dp_Res1)=NextChar;
- Chr=NextChar;
- NextChar=-1;
- Err=1;
- Pkt->dp_Res1++;
- if (Pkt->dp_Res1==Pkt->dp_Arg3 || Chr=='\r' || Chr=='\n') {
- Remove(ReadWaitList.lh_Head);
- PutMsg(Pkt->dp_Port,Pkt->dp_Link); /* Send it back */
- }
- }
- }
- if (ReadWaitList.lh_Head->ln_Succ && !HangupFlag) {
- FD_SET(Socket,&RdSet);
- } else {
- FD_CLR(Socket,&RdSet);
- }
- SigMask=(1<<((struct Process *)FindTask(NULL))->pr_MsgPort.mp_SigBit)|(1<<TimePort->mp_SigBit);
- WaitSelect(Socket+1,&RdSet,NULL,NULL,NULL,&SigMask);
- #ifdef DEBUG
- PktFPuts(Inst,DebugFile,"Wait ended \n");
- #endif
-
- if (FD_ISSET(Socket,&RdSet)) {
- #ifdef DEBUG
- PktFPuts(Inst,DebugFile,"Got read available from socket\n");
- #endif
- if (ReadWaitList.lh_Head->ln_Succ) {
- /* Someone is waiting to read */
- Pkt=PktFromMsg((struct Message *)ReadWaitList.lh_Head);
- if (Pkt && Pkt->dp_Type==ACTION_READ) {
- #ifdef DEBUG
- PktFPuts(Inst,DebugFile,"Performing delayed read\n");
- #endif
- while (Pkt->dp_Res1 < Pkt->dp_Arg3) {
- if (NextChar != -1) {
- *(((unsigned char *)Pkt->dp_Arg2)+Pkt->dp_Res1)=NextChar;
- Chr=NextChar;
- NextChar=-1;
- Err=1;
- } else {
- Err=RecvChar(Inst,Socket,((char *)Pkt->dp_Arg2)+Pkt->dp_Res1,FALSE/*RawMode*/);
- Chr=*(((char *)Pkt->dp_Arg2)+Pkt->dp_Res1);
- }
- if (Err==1) Pkt->dp_Res1++;
- else if (Err==0) {
- /* Hangup */
- HangupFlag=TRUE;
- break;
- } else break;
- #ifdef DEBUG
- if (Chr==255) {
- PktFPuts(Inst,DebugFile,"Received 255\n");
- }
- #endif
- if (Chr=='\r' || Chr=='\n') {
- break;
- }
- }
- if (Err==1) {
- if (Pkt->dp_Res1==Pkt->dp_Arg3 ||
- Chr=='\r' || Chr=='\n') {
- Remove(ReadWaitList.lh_Head);
- /* syslog(LOG_DEBUG, "Sending out \"%s\"",
- * &Pkt->dp_Link+sizeof(struct Message));
- */
- PutMsg(Pkt->dp_Port,Pkt->dp_Link); /* Send it back */
- }
- }
- } else if (Pkt && Pkt->dp_Type==ACTION_WAIT_CHAR) {
- #ifdef DEBUG
- PktFPuts(Inst,DebugFile,"Processing WAIT_CHAR");
- #endif
- if (NextChar==-1) {
- Err=RecvChar(Inst,Socket,&Chr,FALSE);
- if (Err==1) {
- Pkt->dp_Res1=DOSTRUE;
- Remove(ReadWaitList.lh_Head);
- #ifdef DEBUG
- PktFPuts(Inst,DebugFile,"char ready\n");
- #endif
- AbortIO((struct IORequest *)Pkt->dp_Res2);
- WaitIO((struct IORequest *)Pkt->dp_Res2);
- CloseDevice((struct IORequest *)Pkt->dp_Res2);
- DeleteIORequest((struct IORequest *)Pkt->dp_Res2);
- Pkt->dp_Res2=0;
- PutMsg(Pkt->dp_Port,Pkt->dp_Link);
- NextChar=Chr;
- } else {
- #ifdef DEBUG
- PktFPuts(Inst,DebugFile,"no char available\n");
- #endif
- NextChar=-1;
- }
- if (Err==0) HangupFlag=TRUE;
- } else {
- Pkt->dp_Res1=DOSTRUE;
- Remove(ReadWaitList.lh_Head);
- AbortIO((struct IORequest *)Pkt->dp_Res2);
- WaitIO((struct IORequest *)Pkt->dp_Res2);
- CloseDevice((struct IORequest *)Pkt->dp_Res2);
- DeleteIORequest((struct IORequest *)Pkt->dp_Res2);
- Pkt->dp_Res2=0;
- PutMsg(Pkt->dp_Port,Pkt->dp_Link);
- #ifdef DEBUG
- PktFPuts(Inst,DebugFile,"char ready\n");
- #endif
- }
- }
- else { /* Invalid message */
- Remove(ReadWaitList.lh_Head);
- }
- } else {
- #ifdef DEBUG
- PktFPuts(Inst,DebugFile,"Unexpected: got read ready, no request\n");
- #endif
- }
- }
- while (TimeReq=(struct timerequest *)GetMsg(TimePort)) {
- Msg=(struct Message *)TimeReq->tr_node.io_Message.mn_Node.ln_Name;
- Pkt=PktFromMsg(Msg);
- CloseDevice(TimeReq);
- DeleteIORequest(TimeReq);
- Pkt->dp_Res1=DOSFALSE;
- Pkt->dp_Res2=0;
- Remove(Msg); /* Remove it from the read wait list */
- PutMsg(Pkt->dp_Port,Pkt->dp_Link);
-
-
- }
- while (Msg=GetMsg(&((struct Process *)FindTask(NULL))->pr_MsgPort)) {
- Pkt=PktFromMsg(Msg);
- #ifdef DEBUG
- PktFPuts(Inst,DebugFile,"Got packet\n");
- #endif
- switch(Pkt->dp_Type) {
- case ACTION_FINDINPUT:
- case ACTION_FINDOUTPUT:
- case ACTION_FINDUPDATE:
- FH=(struct FileHandle *)BADDR((BPTR)Pkt->dp_Arg1);
- FH->fh_Pos=FH->fh_End=-1;
- FH->fh_Type=&((struct Process *)FindTask(NULL))->pr_MsgPort;
- FH->fh_Args=(LONG)Info;
- FH->fh_Port=FH->fh_Type; /* Is this right? */
- OpenCount++;
- Pkt->dp_Res1=DOSTRUE;
- PutMsg(Pkt->dp_Port,Pkt->dp_Link);
- break;
-
- case ACTION_READ:
- Pkt->dp_Res1=0;
- #ifdef DEBUG
- PktFPuts(Inst,DebugFile,"Got action_read\n");
- #endif
- AddTail(&ReadWaitList,Msg);
- break;
-
- case ACTION_WRITE:
- #ifdef DEBUG
- PktFPuts(Inst,DebugFile,"Got action_write\n");
- #endif
- SockWrite(Inst,Socket,(char *)Pkt->dp_Arg2,Pkt->dp_Arg3,FALSE/*RawMode*/);
- Pkt->dp_Res1=Pkt->dp_Arg3;
- PutMsg(Pkt->dp_Port,Pkt->dp_Link);
- break;
-
- case ACTION_WAIT_CHAR:
- #ifdef DEBUG
- PktFPuts(Inst,DebugFile,"Got action_waitchar");
- #endif
- Pkt->dp_Res1=DOSFALSE;
-
- TimeReq=CreateIORequest(TimePort,sizeof(struct timerequest));
- if (!TimeReq || OpenDevice("timer.device",UNIT_MICROHZ,TimeReq,0)) {
- if (TimeReq)
- DeleteIORequest(TimeReq);
- Pkt->dp_Res2=ERROR_NO_FREE_STORE;
- PutMsg(Pkt->dp_Port,Pkt->dp_Link);
- }
- TimeReq->tr_node.io_Command=TR_ADDREQUEST;
- TimeReq->tr_time.tv_micro=Pkt->dp_Arg1;
- TimeReq->tr_time.tv_secs=0;
- TimeReq->tr_node.io_Message.mn_Node.ln_Name=Msg;
- SendIO(TimeReq);
- Pkt->dp_Res2=(ULONG)TimeReq;
-
- AddTail(&ReadWaitList,Msg);
-
- break;
-
- /*
- case ACTION_DISKINFO:
-
- break;
- */
- case ACTION_SCREEN_MODE:
- #ifdef DEBUG
- PktFPuts(Inst,DebugFile,"Got action_screen_mode\n");
- #endif
- if (Pkt->dp_Arg1) {
- /* Raw mode */
- SockPuts(Inst,Socket,NoEcho);
- RawMode=TRUE;
- } else {
- SockPuts(Inst,Socket,Echo);
- RawMode=FALSE;
- }
- Pkt->dp_Res1=DOSFALSE;
- PutMsg(Pkt->dp_Port,Pkt->dp_Link);
- break;
-
- case ACTION_END:
- #ifdef DEBUG
- PktFPuts(Inst,DebugFile,"Got action_end\n");
- #endif
- Pkt->dp_Res1=0;
- PutMsg(Pkt->dp_Port,Pkt->dp_Link);
- OpenCount--;
- if (!OpenCount) {
- for (GotMsg=(struct Message *)ReadWaitList.lh_Head;GotMsg->mn_Node.ln_Succ;GotMsg=(struct Message *)GotMsg->mn_Node.ln_Succ) {
- Pkt=PktFromMsg(GotMsg);
- if (Pkt->dp_Type==ACTION_WAIT_CHAR) {
- AbortIO((struct IORequest *)Pkt->dp_Res2);
- WaitIO((struct IORequest *)Pkt->dp_Res2);
- CloseDevice((struct IORequest *)Pkt->dp_Res2);
- DeleteIORequest((struct IORequest *)Pkt->dp_Res2);
- Pkt->dp_Res2=0;
- }
- }
-
- goto quit;
- }
- break;
-
- case ACTION_SEEK:
- #ifdef DEBUG
- PktFPuts(Inst,DebugFile,"Got action_seek\n");
- #endif
- Pkt->dp_Res1=-1;
- Pkt->dp_Res2=ERROR_OBJECT_WRONG_TYPE;
- PutMsg(Pkt->dp_Port,Pkt->dp_Link);
-
- break;
-
-
- default:
- #ifdef DEBUG
- PktFPuts(Inst,DebugFile,"Got action_not_known. Number");
- MakeLongStr(NumBuf,Pkt->dp_Type);
- PktFPuts(Inst,DebugFile,NumBuf);
- PktFPuts(Inst,DebugFile,"\n");
- #endif
- Pkt->dp_Res1=0;
- Pkt->dp_Res2=ERROR_ACTION_NOT_KNOWN;
- PutMsg(Pkt->dp_Port,Pkt->dp_Link);
- }
- }
- }
- } else {
- /* Use fake serial */
- struct IOStdReq *IOReq=NULL;
- struct MsgPort *IOPort=NULL;
- struct FSRUnit *SerUnit=NULL;
- /* SerUnit->fsru_UserData[0]=CmdPort
- SerUnit->fsru_UserData[1]=ReadQueue
- SerUnit->fsru_UserData[2]=WriteQueue
- SerUnit->fsru_UserData[3]=Open count
- SerUnit->fsru_UserData[4]=RBufLen */
- struct MsgPort *CmdPort=NULL;
- struct List *ReadQueue=NULL;
- struct List *WriteQueue=NULL;
- char *CmdPtr;
- struct IOExtSer *GotReq=NULL,*OtrReq=NULL;
- char *RBuf=NULL;
- int RBufPos=0;
- int SerUnitAdded=FALSE;
- int Amnt;
- int RecvRet;
- int CD=TRUE; /* Carrier Detect */
- long UnitNum=FSR_UNITNONE;
-
- /* We use IOExtSer.Status bit 0 as a flag to say whether this request has
- been aborted */
-
- #ifdef DEBUG
- FPuts(DebugFile,"Creating ports...\n");
- #endif
- IOPort=CreateMsgPort();
- CmdPort=CreateMsgPort();
- IOReq=CreateIORequest(IOPort,sizeof(struct IOStdReq));
- if (!IOPort || !IOReq || !CmdPort) {
- #ifdef DEBUG
- FPuts(DebugFile,"Unable to create message port/IORequest\nExiting\n");
- #endif
- goto quitfakeser;
- }
- #ifdef DEBUG
- FPuts(DebugFile,"Opening fakesr.device...\n");
- #endif
- if (OpenDevice("fakesr.device",FSR_CTLUNIT,IOReq,0)) {
- IOReq->io_Device=NULL;
- #ifdef DEBUG
- FPuts(DebugFile,"Unable to open fakesr.device\nExiting\n");
- #endif
- goto quitfakeser;
- }
- #ifdef DEBUG
- FPuts(DebugFile,"opened successfully\n");
- #endif
- SerUnit=AllocMem(sizeof(struct FSRUnit),MEMF_CLEAR|MEMF_PUBLIC);
- ReadQueue=AllocMem(sizeof(struct List),MEMF_PUBLIC);
- if (ReadQueue) NewList(ReadQueue);
- WriteQueue=AllocMem(sizeof(struct List),MEMF_PUBLIC);
- if (WriteQueue) NewList(WriteQueue);
- if (!SerUnit || !ReadQueue || !WriteQueue) {
- #ifdef DEBUG
- FPuts(DebugFile,"Unable to allocate memory\nExiting\n");
- #endif
- goto quitfakeser;
- }
-
- CmdPtr=Info->Command;
- if (Info->Command[0]<='9' && Info->Command[0] >= '0') {
- UnitNum=GetInt(Info->Command,&CmdPtr);
- }
-
- SerUnit->fsru_Num=UnitNum;
- SerUnit->fsru_BeginIO=FakeBeginIO;
- SerUnit->fsru_AbortIO=FakeAbortIO;
- SerUnit->fsru_Open=FakeOpen;
- SerUnit->fsru_Close=FakeClose;
- SerUnit->fsru_UserData[0]=CmdPort;
- SerUnit->fsru_UserData[1]=ReadQueue;
- SerUnit->fsru_UserData[2]=WriteQueue;
- SerUnit->fsru_UserData[3]=0;
- SerUnit->fsru_UserData[4]=(void *)1024;
-
- IOReq->io_Data=(APTR)SerUnit;
- IOReq->io_Length=sizeof(*SerUnit);
- IOReq->io_Command=FSRCMD_ADDUNIT;
- IOReq->io_Error=0;
- #ifdef DEBUG
- FPuts(DebugFile,"Adding FakeSr unit...");
- #endif
-
- DoIO(IOReq);
- if (IOReq->io_Error) {
- #ifdef DEBUG
- FPuts(DebugFile,"Error adding fakesr.device unit\nExiting\n");
- #endif
- goto quitfakeser;
- }
-
- SerUnitAdded=TRUE;
-
- #ifdef DEBUG
- FPuts(DebugFile,"Done\n");
- #endif
-
- RBuf=AllocMem((ULONG)SerUnit->fsru_UserData[4],MEMF_PUBLIC);
- RBufPos=0;
- if (!RBuf) {
- #ifdef DEBUG
- FPuts(DebugFile,"Unable to allocate memory\nExiting\n");
- #endif
- goto quitfakeser;
- }
-
-
- IoctlSocket(Socket,FIONBIO,(caddr_t)&yes);
- {
- BPTR NilInput,NilOutput;
- #ifdef DEBUG
- FPuts(DebugFile,"Opening filehandles\n");
- #endif
- if (*CmdPtr) {
- NilInput=Open("NIL:",MODE_OLDFILE);
- NilOutput=Open("NIL:",MODE_OLDFILE);
-
- /* sprintf(Buf,"%s -DEVICE fakesr.device -UNIT %ld",CmdPtr,SerUnit->fsru_Num); */
- strcpy(Buf,CmdPtr);
- mystrcat(Buf," -DEVICE fakesr.device -UNIT ");
- MakeLongStr(LoginBuf,SerUnit->fsru_Num);
- #ifdef DEBUG
- FPuts(DebugFile,"Got FakeSr unit: ");
- FPuts(DebugFile,LoginBuf);
- FPuts(DebugFile,"\n");
- #endif
- SockPuts(Inst,Socket,NoEcho);
-
- mystrcat(Buf,LoginBuf);
- #ifdef DEBUG
- FPuts(DebugFile,"Running command:");
- FPuts(DebugFile,Buf);
- FPuts(DebugFile,"\n");
- #endif
- MySystemTags(DOSBase,Buf,SYS_Input,NilInput,SYS_Output,NilOutput,SYS_Asynch,TRUE,TAG_END);
- }
- }
-
- for (;;) {
- FD_ZERO(&RdSet);
- FD_ZERO(&WrSet);
- if (CD) {
- if (RBufPos < (((long)SerUnit->fsru_UserData[4])-1)) FD_SET(Socket,&RdSet);
- if (WriteQueue->lh_Head->ln_Succ) FD_SET(Socket,&WrSet);
- }
- SigMask=(1<<CmdPort->mp_SigBit)|SIGBREAKF_CTRL_C;
- WaitSelect(Socket+1,&RdSet,&WrSet,NULL,NULL,&SigMask);
- #ifdef DEBUG
- FPuts(DebugFile,"Wait ended...");
- #endif
-
- if (FD_ISSET(Socket,&RdSet)) {
- while ((RBufPos < (long)SerUnit->fsru_UserData[4]) && ((RecvRet=RecvChar(Inst,Socket,RBuf+RBufPos,TRUE))==1)) RBufPos++;
- Forbid();
- if ((GotReq=(struct IOExtSer *)ReadQueue->lh_Head)->IOSer.io_Message.mn_Node.ln_Succ) {
- Remove(GotReq);
- Permit();
- Amnt=min(RBufPos,GotReq->IOSer.io_Length);
- memcpy(((char *)GotReq->IOSer.io_Data)+GotReq->IOSer.io_Actual,RBuf,Amnt);
- GotReq->IOSer.io_Actual+=Amnt;
- if (Amnt < RBufPos) mymovmem(RBuf+Amnt,RBuf,RBufPos-Amnt);
- RBufPos-=Amnt;
-
- if (GotReq->IOSer.io_Actual < GotReq->IOSer.io_Length) {
- if (GotReq->io_Status & (1<<0)) {
- /* We got an AbortIO() */
- GotReq->IOSer.io_Error=IOERR_ABORTED;
- ReplyMsg(GotReq);
- } else {
- Forbid();
- AddTail(ReadQueue,GotReq);
- Permit();
- }
- }
- else ReplyMsg(GotReq);
-
- }
- else Permit();
- if (RecvRet==0) {
- /* Connection closed */
- CD=FALSE;
- }
- }
- if (FD_ISSET(Socket,&WrSet)) {
- Forbid();
- if ((GotReq=(struct IOExtSer *)WriteQueue->lh_Head)->IOSer.io_Message.mn_Node.ln_Succ) {
- Remove(GotReq);
- Permit();
-
- #ifdef DEBUG
- FPuts(DebugFile,"Writing to socket\n");
- MyFPrintf(Inst,DebugFile,"io_Actual=%ld,io_Length=%ld\n",(long)GotReq->IOSer.io_Actual,(long)GotReq->IOSer.io_Length);
- #endif
- SockWrite(Inst,Socket,((char *)GotReq->IOSer.io_Data)+GotReq->IOSer.io_Actual,GotReq->IOSer.io_Length-GotReq->IOSer.io_Actual,TRUE);
- #ifdef DEBUG
- FPuts(DebugFile,"Write completed\n");
- #endif
- GotReq->IOSer.io_Actual=GotReq->IOSer.io_Length;
-
-
- if (GotReq->IOSer.io_Actual < GotReq->IOSer.io_Length) {
- Forbid();
- if (GotReq->io_Status & (1<<0)) {
- Permit();
- /* We got an AbortIO() */
- GotReq->IOSer.io_Error=IOERR_ABORTED;
- ReplyMsg(GotReq);
- } else {
- AddTail(WriteQueue,GotReq);
- Permit();
- }
- } else {
- #ifdef DEBUG
- FPuts(DebugFile,"Replying write message\n");
- #endif
- ReplyMsg(GotReq);
- }
-
-
- } else {
-
- Permit();
- }
- }
- while (GotReq=(struct IOExtSer *)GetMsg(CmdPort)) {
- if (GotReq->IOSer.io_Message.mn_Node.ln_Name==Signature) {
- /* We just use the pointer as a signature */
- /* We just got an expunge request */
- #ifdef DEBUG
- FPuts(DebugFile,"Got expunge request\n");
- #endif
-
- FreeMem(GotReq,sizeof(struct Message)); /* We free the expunge request instead of reply */
-
- Forbid();
- if (SerUnit->fsru_UserData[3]==0) {
- /* Open count==0 */
- if (SerUnitAdded) {
- IOReq->io_Command=FSRCMD_REMUNIT;
- IOReq->io_Data=(APTR)SerUnit;
- IOReq->io_Length=sizeof(*SerUnit);
- DoIO(IOReq);
- SerUnitAdded=FALSE;
- }
- if (SerUnit->fsru_UserData[3]==0) {
- /* If opencnt is still 0 */
- Permit();
- goto quitfakeser; /* exit */
- }
- }
- Permit();
- }
- else {
- #ifdef DEBUG
- FPuts(DebugFile,"Got cmd...");
- #endif
-
- switch(GotReq->IOSer.io_Command) {
- case CMD_CLEAR:
- #ifdef DEBUG
- FPuts(DebugFile,"Got CMD_CLEAR\n");
- #endif
- RBufPos=0;
- GotReq->IOSer.io_Error=0;
- ReplyMsg(GotReq);
- break;
-
- case CMD_FLUSH:
- case CMD_RESET:
- #ifdef DEBUG
- FPuts(DebugFile,"Got CMD_FLUSH/RESET\n");
- #endif
-
- Forbid();
- while (OtrReq=(struct IOExtSer *)RemHead(ReadQueue)) {
- OtrReq->IOSer.io_Error=IOERR_ABORTED;
- ReplyMsg(OtrReq);
- }
- while (OtrReq=(struct IOExtSer *)RemHead(WriteQueue)) {
- OtrReq->IOSer.io_Error=IOERR_ABORTED;
- ReplyMsg(OtrReq);
- }
- Permit();
- GotReq->IOSer.io_Error=0;
- ReplyMsg(GotReq);
- break;
-
- case CMD_READ:
- #ifdef DEBUG
- FPuts(DebugFile,"Got CMD_READ\n");
- #endif
-
- GotReq->IOSer.io_Actual=0;
- GotReq->IOSer.io_Error=0;
- Amnt=min(RBufPos,GotReq->IOSer.io_Length);
- memcpy(((char *)GotReq->IOSer.io_Data)+GotReq->IOSer.io_Actual,RBuf,Amnt);
- GotReq->IOSer.io_Actual+=Amnt;
- if (Amnt < RBufPos) mymovmem(RBuf+Amnt,RBuf,Amnt);
- RBufPos-=Amnt;
-
- if (GotReq->IOSer.io_Actual < GotReq->IOSer.io_Length) {
- Forbid();
- AddTail(ReadQueue,GotReq);
- Permit();
- }
- else ReplyMsg(GotReq);
- break;
-
- case CMD_START:
- #ifdef DEBUG
- FPuts(DebugFile,"Got CMD_START\n");
- #endif
-
- GotReq->IOSer.io_Error=0;
- ReplyMsg(GotReq);
- break;
-
- case CMD_STOP:
- #ifdef DEBUG
- FPuts(DebugFile,"Got CMD_STOP\n");
- #endif
-
- GotReq->IOSer.io_Error=0;
- ReplyMsg(GotReq);
- break;
-
- case CMD_WRITE:
- #ifdef DEBUG
- FPuts(DebugFile,"Got CMD_WRITE\n");
- #endif
-
- GotReq->IOSer.io_Actual=0;
- GotReq->IOSer.io_Error=0;
- Forbid();
- AddTail(WriteQueue,GotReq);
- Permit();
- break;
-
- case SDCMD_BREAK:
- #ifdef DEBUG
- FPuts(DebugFile,"Got SDCMD_BREAK\n");
- #endif
-
- GotReq->IOSer.io_Error=0;
- ReplyMsg(GotReq);
- break;
-
- case SDCMD_QUERY:
- #ifdef DEBUG
- FPuts(DebugFile,"Got SDCMD_QUERY\n");
- #endif
-
- GotReq->IOSer.io_Actual=RBufPos;
- GotReq->io_Status=0x0000 | ((CD) ? 0:(1<<5));
- GotReq->IOSer.io_Error=0;
-
- ReplyMsg(GotReq);
- break;
-
- case SDCMD_SETPARAMS:
- #ifdef DEBUG
- FPuts(DebugFile,"Got SDCMD_SETPARAMS\n");
- #endif
-
- GotReq->IOSer.io_Error=0;
- ReplyMsg(GotReq);
- break;
-
- default:
- #ifdef DEBUG
- FPuts(DebugFile,"Got CMD_UNKNOWN\n");
- #endif
- GotReq->IOSer.io_Error=IOERR_NOCMD;
- ReplyMsg(GotReq);
-
- }
- }
- }
- }
-
-
- quitfakeser:
-
- if (ReadQueue) {
- Forbid();
- while (GotReq=(struct IOExtSer *)RemHead(ReadQueue)) {
- GotReq->IOSer.io_Error=IOERR_ABORTED;
- GotReq->IOSer.io_Actual=0;
- ReplyMsg(GotReq);
- }
- Permit();
- FreeMem(ReadQueue,sizeof(struct List));
- }
- if (WriteQueue) {
- Forbid();
- while (GotReq=(struct IOExtSer *)RemHead(WriteQueue)) {
- GotReq->IOSer.io_Error=IOERR_ABORTED;
- GotReq->IOSer.io_Actual=0;
- ReplyMsg(GotReq);
- }
- Permit();
- FreeMem(WriteQueue,sizeof(struct List));
- }
- if (RBuf && SerUnit) {
- FreeMem(RBuf,(long)SerUnit->fsru_UserData[4]);
- }
- if (SerUnit) {
- if (SerUnitAdded && IOReq) {
- IOReq->io_Data=(APTR)SerUnit;
- IOReq->io_Length=sizeof(*SerUnit);
- IOReq->io_Command=FSRCMD_REMUNIT;
- DoIO(IOReq);
- }
- FreeMem(SerUnit,sizeof(struct FSRUnit));
- }
- if (IOReq) {
- if (IOReq->io_Device) CloseDevice(IOReq);
- DeleteIORequest(IOReq);
- }
- if (IOPort) DeleteMsgPort(IOPort);
- if (CmdPort) DeleteMsgPort(CmdPort);
- goto quit;
- }
-
- quit:
- #ifdef DEBUG
- if (DebugFile) Close(DebugFile);
- #endif
- SocketBaseTags(SBTM_SETVAL(SBTC_LOGTAGPTR), NULL, TAG_END);
- if (TimePort) DeleteMsgPort(TimePort);
- if (Info) FreeMem(Info,sizeof(struct PasswdInfo));
- if (Inst) {
- if (UserGroupBase) CloseLibrary(UserGroupBase);
- if (SocketBase) CloseLibrary(SocketBase);
- if (UtilityBase) CloseLibrary(UtilityBase);
- if (DOSBase) CloseLibrary(DOSBase);
- }
- return 0;
- }
-
- void MyFPrintf(struct InstData *Inst,BPTR File,char *Fmt,...)
- {
- VFPrintf(File,Fmt,(&Fmt)+1);
- }
-
- void mystrcat(char *Dest,char *Cat)
- {
- memcpy(Dest+strlen(Dest),Cat,strlen(Cat)+1);
- }
-
- void mymovmem(char *From,char *To,int Len)
- {
- int Cnt;
- if (From > To) {
- for (Cnt=0;Cnt < Len;Cnt++) {
- To[Cnt]=From[Cnt];
- }
- } else if (From < To) {
- for (Cnt=Len-1;Cnt >= 0;Cnt--) {
- To[Cnt]=From[Cnt];
- }
- }
- }
-
- struct Node *FindNode(struct List *List,struct Node *Node)
- /* returns Node if Node is a member of list, NULL otherwise */
- {
- struct Node *ChkNode;
-
- for (ChkNode=List->lh_Head;ChkNode->ln_Succ;ChkNode=ChkNode->ln_Succ) {
- if (ChkNode==Node) return Node;
- }
- return NULL;
- }
-
- ULONG FakeBeginIO(void *IORequest)
- {
- ((struct IORequest *)IORequest)->io_Flags &= ~IOF_QUICK; /* Quick IO not supported */
- ((struct IOExtSer *)IORequest)->io_Status &= ~(1<<0); /* clear abort bit */
- ((struct Node *)IORequest)->ln_Name=NULL; /* clear possible signature */
- PutMsg((struct MsgPort *)((struct FSRUnit *)((struct IORequest *)IORequest)->io_Unit)->fsru_UserData[0],IORequest);
- return 0;
- }
-
- ULONG FakeAbortIO(void *IORequest)
- {
- struct IOExtSer *Ser;
-
- Ser=IORequest;
- Forbid();
- Ser->io_Status |= (1<<0); /* Flag the request as aborted */
- if (FindNode(((struct FSRUnit *)Ser->IOSer.io_Unit)->fsru_UserData[1],Ser) ||
- FindNode(((struct FSRUnit *)Ser->IOSer.io_Unit)->fsru_UserData[2],Ser)) {
- /* This IORequest is waiting to be processed */
- Remove(Ser);
- Ser->IOSer.io_Error=IOERR_ABORTED;
- Ser->IOSer.io_Actual=0;
- ReplyMsg(Ser);
- }
- else {
- /* This IORequest is currently being processed -- send a break */
- Signal(((struct MsgPort *)((struct FSRUnit *)Ser->IOSer.io_Unit)->fsru_UserData[0])->mp_SigTask,SIGBREAKF_CTRL_C);
- }
- Permit();
-
- return 0;
- }
-
- ULONG FakeOpen(void *IORequest)
- {
- struct IOExtSer *Ser;
-
- Ser=IORequest;
- Forbid();
- ((struct FSRUnit *)Ser->IOSer.io_Unit)->fsru_UserData[3]=(void *) ((long)(((struct FSRUnit *)Ser->IOSer.io_Unit)->fsru_UserData[3])+1); /* Increment opencnt */
- Permit();
- Ser->IOSer.io_Error=0;
- Ser->io_CtlChar=SER_DEFAULT_CTLCHAR;
- Ser->io_RBufLen=(long)((struct FSRUnit *)Ser->IOSer.io_Unit)->fsru_UserData[4];
- Ser->io_ExtFlags=0;
- Ser->io_Baud=19200;
- Ser->io_BrkTime=250000;
- Ser->io_TermArray.TermArray0=0;
- Ser->io_TermArray.TermArray1=0;
- Ser->io_ReadLen=8;
- Ser->io_WriteLen=8;
- Ser->io_StopBits=1;
- Ser->io_Status=0;
- return 0;
- }
-
- ULONG FakeClose(void *IORequest)
- {
- struct IOExtSer *Ser;
- struct Message *Msg;
-
- Ser=IORequest;
- Forbid();
-
- ((struct FSRUnit *)Ser->IOSer.io_Unit)->fsru_UserData[3]=(void *) ((long)(((struct FSRUnit *)Ser->IOSer.io_Unit)->fsru_UserData[3])-1); /* Decrement opencnt */
- Msg=AllocMem(sizeof(struct Message),MEMF_PUBLIC|MEMF_CLEAR);
- Msg->mn_Node.ln_Name=Signature;
- PutMsg((struct MsgPort *)((struct FSRUnit *)((struct IORequest *)IORequest)->io_Unit)->fsru_UserData[0],Msg);
-
- Permit();
- return 0;
- }
-
-
- struct DosPacket *PktFromMsg(struct Message *Msg)
- {
- return (struct DosPacket *)Msg->mn_Node.ln_Name;
- }
-
- void PktFPuts(struct InstData *Inst,BPTR File,char *String)
- {
- struct MsgPort *ReplyPort;
- struct DosPacket *Pkt;
-
- ReplyPort=CreateMsgPort();
- Pkt=AllocDosObject(DOS_STDPKT,NULL);
- if (!Pkt || !ReplyPort) return;
-
- Pkt->dp_Type=ACTION_WRITE;
- Pkt->dp_Arg1=((struct FileHandle *)BADDR(File))->fh_Arg1;
- Pkt->dp_Arg2=(LONG) String;
- Pkt->dp_Arg3=strlen(String);
- Pkt->dp_Port=ReplyPort;
- PutMsg(((struct FileHandle *)BADDR(File))->fh_Type,Pkt->dp_Link);
- WaitPort(ReplyPort);
- GetMsg(ReplyPort);
- DeleteMsgPort(ReplyPort);
- FreeDosObject(DOS_STDPKT,Pkt);
- }
-
- unsigned long GetInt(char *String,char **NewPtr)
- {
- unsigned long Num=0;
- char *Junk;
- long Cnt;
- long BaseNum;
-
- if (!NewPtr) NewPtr=&Junk;
-
- for (*NewPtr=String;;(*NewPtr)++) {
-
- if (**NewPtr < '0' || **NewPtr > '9') return Num;
-
- /* AAARGH!! multiplication causes a lib call to be generated.
- We can't use the library. Therefore we have to add */
- /* Num=Num*10; */
- for (BaseNum=Num,Cnt=0;Cnt < 9;Cnt++,Num+=BaseNum);
-
-
- Num+=**NewPtr-'0';
- }
-
- }
-
-
- void SockPuts(struct InstData *Inst,int Sock,char *Buf)
- {
- int BufPos=0;
- int BytesWritten;
-
- do {
- BytesWritten=send(Sock,Buf+BufPos,strlen(Buf+BufPos),0);
- if (BytesWritten > 0) BufPos+=BytesWritten;
- } while (Buf[BufPos]);
- }
-
- void SockRawWrite(struct InstData *Inst,int Sock,char *Buf,int Len)
- {
- int BufPos=0;
- int BytesWritten;
-
- if (!Len) return;
-
- do {
- BytesWritten=send(Sock,Buf+BufPos,Len-BufPos,0);
- if (BytesWritten > 0) BufPos+=BytesWritten;
- } while (Len-BufPos);
-
- }
-
- void SockWrite(struct InstData *Inst,int Sock,char *Buf,int Len,int RawFlag)
- {
- int Cnt;
- int BufPos=0;
- unsigned char iac2[2];
- char eol[2];
- char csi[2];
- iac2[0]=iac2[1]=IAC;
- eol[0]='\r';
- eol[1]='\n';
- csi[0]='\x1b';
- csi[1]='[';
-
-
- while (Len > BufPos) {
- for (Cnt=BufPos;Cnt < Len;Cnt++) {
- if (!RawFlag)
- if (Buf[Cnt]=='\r' || Buf[Cnt]=='\n') break;
- if (Buf[Cnt]=='\x9b') break;
- if (Buf[Cnt]==IAC) {
- break;
- }
- }
- SockRawWrite(Inst,Sock,Buf+BufPos,Cnt-BufPos);
- BufPos=Cnt;
- if (BufPos < Len && Buf[BufPos]==IAC) { /* If we got single IAC, send double IAC */
- BufPos++;
- SockRawWrite(Inst,Sock,iac2,2);
- }
- if (!RawFlag) {
- if (BufPos < Len && Buf[BufPos]=='\r') {
- BufPos++;
- }
- if (BufPos < Len && Buf[BufPos]=='\n') {
- BufPos++;
- SockRawWrite(Inst,Sock,eol,2);
- }
- if (BufPos < Len && Buf[BufPos]=='\x9b') {
- BufPos++;
- SockRawWrite(Inst,Sock,csi,2);
- }
- }
- }
- }
-
- void ParseBuf3(struct InstData *Inst)
- /* Parse 3 character remote request */
- {
-
- }
-
- void ParseBuf2(struct InstData *Inst)
- /* Parse 2 character remote-request */
- {
-
- }
-
- void ParseBufSubNegotiate(struct InstData *Inst)
- {
-
- }
-
- int RecvChar(struct InstData *Inst,int Sock,unsigned char *Loc,int RawMode)
- {
- int GotLen;
- unsigned char Got,TrueGot;
- /*RawMode=TRUE;*/
- static unsigned char PrevChar;
-
- do {
-
- GotLen=recv(Sock,&Got,1,0); /* Wait for a character */
- if (GotLen==-1) {
- if (Errno()==EINTR) continue;
- else return -1;
- } else if (GotLen==0) return 0;
-
- TrueGot=Got;
- if (!Inst->RecvBufPos && GotLen==1 && Got==0) GotLen=-1; /* Read again */
- if (GotLen==1 && !RawMode && !Inst->RecvBufPos) {
- /* These next few lines ignore incoming newlines and convert
- incoming CRs into newlines */
- if (Got=='\n' && PrevChar=='\r') GotLen=-1; /* Read again. */
- if (Got=='\r') Got='\n';
- }
- } while (GotLen != 1);
- /* *Loc=Got;
- return 1; */
-
- if (Inst->RecvBufPos) {
- Inst->RecvBuf[Inst->RecvBufPos]=Got;
- Inst->RecvBufPos++;
- switch (Inst->RecvBufPos) {
- case 2:
- switch(Inst->RecvBuf[1]) {
- case IAC:
- /* Just a single IAC */
- *Loc=IAC;
- return 1;
- break;
-
- case SB:
- Inst->RecvBufFlags|=RBF_SUBNEGOTIATE;
- return RecvChar(Inst,Sock,Loc,RawMode);
- break;
-
- case SE:
- Inst->RecvBufPos=0;
- Inst->RecvBufFlags &= ~RBF_SUBNEGOTIATE;
- return RecvChar(Inst,Sock,Loc,RawMode);
-
- case WILL:
- case WONT:
- case DO:
- case DONT:
- return RecvChar(Inst,Sock,Loc,RawMode);
- break;
-
- default:
- ParseBuf2(Inst);
- Inst->RecvBufPos=0;
- return RecvChar(Inst,Sock,Loc,RawMode);
- }
- break;
-
- default:
- if (Inst->RecvBufFlags & RBF_SUBNEGOTIATE) {
- if (Inst->RecvBufPos >= 2 && Inst->RecvBuf[Inst->RecvBufPos-2]==IAC && Inst->RecvBuf[Inst->RecvBufPos-1]!=IAC) {
- /* End of subnegotiation */
- Inst->RecvBuf[0]=IAC;
- if ((Inst->RecvBuf[1]=Inst->RecvBuf[Inst->RecvBufPos-1])==SE) {
- Inst->RecvBufFlags &= ~RBF_SUBNEGOTIATE;
- Inst->RecvBufPos=0;
- return RecvChar(Inst,Sock,Loc,RawMode);
- }
- Inst->RecvBufPos=2;
-
- ParseBufSubNegotiate(Inst);
- }
-
- if (Inst->RecvBufPos >= 2 && Inst->RecvBuf[Inst->RecvBufPos-2]==IAC && Inst->RecvBuf[Inst->RecvBufPos-1]==IAC) {
- /* We just got a double IAC in subnegotiation */
- Inst->RecvBuf[Inst->RecvBufPos-2]=-1; /* We store IAC as a (int)-1 */
- Inst->RecvBufPos--;
- }
- return RecvChar(Inst,Sock,Loc,RawMode);
- } else {
- if (Inst->RecvBuf[2]==IAC) {
- /* Restart sequence */
- Inst->RecvBuf[0]=IAC;
- Inst->RecvBufPos=1;
- return RecvChar(Inst,Sock,Loc,RawMode);
- } else {
- ParseBuf3(Inst);
- Inst->RecvBufPos=0;
- return RecvChar(Inst,Sock,Loc,RawMode);
- }
- }
- break;
- }
- }
- else {
- if (Got==IAC) {
- Inst->RecvBuf[0]=Got;
- Inst->RecvBufPos=1;
- return RecvChar(Inst,Sock,Loc,RawMode);
- } else {
- *Loc=Got;
- PrevChar=TrueGot;
- return 1;
- }
- }
- return 1;
-
- }
-
-
- void SockGets(struct InstData *Inst,int Sock,char *Buf,int BufSize)
- /* This function gets the next string until a CR
- on the specified socket, and places it in buf. It
- discards leading crs/lfs */
- {
- int BufPos=0;
- int BytesRead;
- int FirstBytes=TRUE;
- Buf[0]='\0';
-
- do {
- BytesRead=RecvChar(Inst,Sock,Buf+BufPos,FALSE);
- if (BytesRead < 0) {
- if (Errno()!=EINTR) {
- Buf[BufPos]='\0';
- return;
- }
- }
- else if (BytesRead==0) {
- Buf[BufPos]='\0';
- return;
- }
- else {
- if ((Buf[BufPos]=='\r' || Buf[BufPos]=='\n') && FirstBytes) {
- Buf[BufPos]='\0';
- } else {
- FirstBytes=FALSE;
- BufPos+=BytesRead;
- }
- }
- } while (Buf[BufPos-1] != '\r' && Buf[BufPos-1] != '\n' && BufPos < (BufSize-1));
- Buf[BufPos]='\0';
- }
-
- char *PullPasswdString(char **StringPtr)
- {
- int Cnt;
- char *RetVal;
- char *CurPos;
-
- if (!StringPtr || !*StringPtr) return NULL;
-
- RetVal=*StringPtr;
-
- for (CurPos=RetVal;*CurPos != ',' && *CurPos != '\r' && *CurPos != '\n' && *CurPos;CurPos++);
- switch (*CurPos) {
- case ',':
- case '\r':
- case '\n':
- *CurPos='\0';
- CurPos++;
- *StringPtr=CurPos;
- return RetVal;
-
- case '\0':
- *StringPtr=CurPos;
- return RetVal;
- }
- }
-
- int mystrcmp(char *S1,char *S2)
- {
- int Cnt;
- for (Cnt=0;S1[Cnt] && S2[Cnt];Cnt++) {
- if (S1[Cnt] != S2[Cnt]) return !0;
- }
- if (S1[Cnt] != S2[Cnt]) return !0;
- return 0;
- }
-
- struct PasswdInfo *LookupPasswd(struct InstData *Inst,char *Login)
- {
- BPTR File;
- char *LineBuf;
- char *BufPtr;
- char *PasswdPtr;
- char *LoginPtr;
- char *RealNamePtr;
- char *HomeDirPtr;
- char *CmdPtr;
- struct PasswdInfo *Info = NULL;
- struct passwd *result;
-
- if (result = getpwnam(Login)) {
- if (Info=AllocMem(sizeof(struct PasswdInfo),MEMF_PUBLIC)) {
- strcpy(Info->Login,result->pw_name);
- strcpy(Info->Passwd,result->pw_passwd);
- strcpy(Info->RealName,result->pw_gecos);
- strcpy(Info->Command,result->pw_shell);
- }
- else
- syslog(LOG_CRIT, "Couldn't allocate my info structure!");
- }
- else
- syslog(LOG_INFO, "user %s is unknown here", Login);
-
- return Info;
- }
-
- void __asm PutMLSChar(register __d0 char Chr,register __a3 char **BufPtr)
- {
- **BufPtr=Chr;
- (*BufPtr)++;
- }
-
- void MakeLongStr(char *StrBuf,unsigned long Num)
- {
- RawDoFmt("%lu",&Num,PutMLSChar,&StrBuf);
- }
-
-
- struct Process *MyCreateNewProcTags(struct InstData *Inst,ULONG Tag1,...)
- {
- return CreateNewProc((struct TagItem *)&Tag1);
- }
-
- void *MyAllocDosObjectTags(struct InstData *Inst,ULONG Type,ULONG Tag1,...)
- {
- return AllocDosObject(Type,(struct TagItem *)&Tag1);
- }
- void MySystemTags(struct Library *DSBse,char *Cmd,ULONG Tag0,...)
- {
- #undef DOSBase
- #define DOSBase DSBse
- SystemTagList(Cmd,(struct TagItem *)&Tag0);
- #undef DOSBase
- }
-
- #define DOSBase DSBse
- int __asm __saveds SubSubProc(register __a0 char *ArgString,register __d0 long Length)
- {
- char StringBuf[1000];
- char *StringPtr;
- BPTR FH;
- struct Library *DSBse;
-
- DSBse=OpenLibrary("dos.library",36);
- if (!DSBse) return 0;
-
- FH=(BPTR)GetInt(ArgString,&StringPtr);
-
- /* if (IsInteractive(FH)) {
- Write(FH,"Interactive\n",12);
- }*/
- strcpy(StringBuf,StringPtr);
- MySystemTags(DSBse,(StringBuf[0]) ? StringBuf : "execute S:remote-startup",
- SYS_Input,FH,
- SYS_Output,FH,
- NP_ConsoleTask,((struct FileHandle *)BADDR(FH))->fh_Type,
- NP_Cli,TRUE,
- TAG_END);
-
- Forbid();
- Close(FH);
- return 0;
- }
- #undef DOSBase
-
-